library(ggplot2)
library(moments)
options(encoding="utf8")

if (is.null(x)) {
    print("No data for building.")
}
if (is.null(t)) {
    t <- "Test Item"
}
if(is.null(n) || n == 0) {
    n <- ceiling(sqrt(length(x)))
}

cl <- c(-3, -2, -1, 0, 1, 2, 3)
# Get the basic data for analysis.
fun.getBasicData <- function(itemData) {
    avgValue <- mean(itemData)
    minValue <- min(itemData)
    maxValue <- max(itemData)
    stdevValue <- sd(itemData)
    rangeValue <- max(itemData) - min(itemData)

    CL <- avgValue + cl * stdevValue
    d <- data.frame(avg=avgValue, min=minValue, max=maxValue, sd=stdevValue, range=rangeValue, ucl=CL[1],sm2=CL[2],sm1=CL[3],sp1=CL[5],sp2=CL[6], lcl=CL[7])

    dlist <- list(d=d,cl=CL)
    return (dlist)
}

basicData <- fun.getBasicData(x)

# build the histogram chart for NDC
fun.buildBar <- function(itemData) {

    tryCatch({
        sx <- sort(itemData)
        bd <- basicData$d
        CL <- basicData$cl

        NDC_CL <<- CL;
        NDC_maxValue <<- bd$max;
        NDC_minValue <<- bd$min;
        curveXValue <- sort(c(sx, CL))

        NDC_kurtosisValue <<- kurtosis(x)
        NDC_skewnessValue <<- skewness(x)

        xlength <- length(curveXValue)

        nd <- data.frame(d=curveXValue);
        idx <- nd$d %in% CL
        nd$d[idx] <- NA
        ry <- dnorm(curveXValue, mean(curveXValue), sd(curveXValue))

        centerx <- rep(bd$avg, times=xlength)
        sigm_m1 <- rep(bd$sm1, times=xlength)
        sigm_m2 <- rep(bd$sm2, times=xlength)
        sigm_p1 <- rep(bd$sp1, times=xlength)
        sigm_p2 <- rep(bd$sp2, times=xlength)
        ucl <- rep(bd$ucl, times=xlength)
        lcl <- rep(bd$lcl, times=xlength)

        dv <- seq(bd$min, bd$max, by=(bd$max - bd$min)/n)
        barValue <- c(0,as.data.frame(table(cut(sx, dv, include.lowest=T)))[,2])

        yMax <- abs(max(barValue) * 1.1)
        liney <- seq(0,yMax,length=xlength)
        dig <- max(barValue)/max(ry)

        #        totalXData <- c(sx,CL)
        #        maxtotal <- max(totalXData)
        #        mintotal <- min(totalXData)
        dc <- data.frame(x=nd$d, rx=curveXValue, y=ry, cx=centerx, cy=liney)

        dvt <- round(as.numeric(dv), 6)

        binsize <- (bd$max - bd$min) / n

        p <- ggplot(dc, aes(x=x))
        p <- p + geom_line(aes(x=cx,y=liney), colour="#568A89") + annotate("text",x=CL[4],y=yMax,label="C",size=2.5,hjust=.5,vjust=-.2, colour="#568A89")
        p <- p + geom_line(aes(x=sigm_p1,y=liney), colour="#71843F") + annotate("text",x=CL[5],y=yMax,label="s",size=2.5,hjust=.5,vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=sigm_m1,y=liney), colour="#71843F") + annotate("text",x=CL[3],y=yMax,label="-s",size=2.5,hjust=.5,vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=sigm_m2,y=liney), colour="#71843F") + annotate("text",x=CL[2],y=yMax,label="-2s",size=2.5,hjust=.5,vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=sigm_p2,y=liney), colour="#71843F") + annotate("text",x=CL[6],y=yMax,label="2s",size=2.5,hjust=.5,vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=ucl,y=liney), colour="brown") + annotate("text",x=CL[7],y=yMax,label="UCL",size=2.5,hjust=.5,vjust=-.2, colour="brown")
        p <- p + geom_line(aes(x=lcl,y=liney), colour="brown") + annotate("text",x=CL[1],y=yMax,label="LCL",size=2.5,hjust=.5,vjust=-.2, colour="brown")
        p <- p + geom_histogram(aes(x=x), na.rm=FALSE, binwidth=binsize, fill="#305d8c",colour="white",origin=min(x),alpha=0.9)
        p <- p + geom_line(aes(x=rx,y=y*dig), colour="red")
        p <- p + scale_x_continuous(breaks=dv,labels=dv)
        p <- p + theme(axis.text.x=element_text(angle=30,size=10,hjust=1,vjust=1))
        p <- p + xlab("")
        p <- p + ylab("Count")
        p <- p + ggtitle(t)
        return (p)
    }, error = function(e) {
        dc <- data.frame(x=c(1:10))
        p3 <- ggplot(dc)+ geom_line(aes(x=0,y=0), colour="red") + ggtitle(t)
        p3 <- p3 +annotate("text",x=0,y=0,label="This item can not be build to a chart.",size=4.5,hjust=.5,vjust=-.2)
        return(p3)
    })
}

# build the run charts
fun.buildRun <- function(itemData, type="RUNC") {
    tryCatch({
        if(is.null(itemData)) {
            print("No data for building.")
            return (NULL)
        }

        claData <- itemData
        if(type == "SDC") {
            group <- matrix(c(claData, rep(NA, (n - length(claData) %% n) %% n)), nrow=n, byrow=T)
            claData <- apply(group, 1, sd, na.rm=T)
        }
        if(type == "XBARC") {
            group <- matrix(c(claData, rep(NA, (n - length(claData) %% n) %% n)), nrow=n, byrow=T)
            claData <- apply(group, 1, mean, na.rm=T)

        }
        if(type == "RC") {
            group <- matrix(c(claData, rep(NA, (n - length(claData) %% n) %% n)), nrow=n, byrow=T)
            claData <- apply(group, 1, max, na.rm=T) - apply(group, 1, min, na.rm=T)
        }
        if(type == "MRC") {
            group <- matrix(c(claData, rep(NA, (n - length(claData) %% n) %% n)), nrow=n, byrow=T)
            group <- matrix(c(claData, rep(NA, (n - length(claData) %% n) %% n)), nrow=n, byrow=T)
            m <- length(itemData)
            claData <- abs(c(claData[2:m], claData[1]) - x[1:m])
        }
        xlength <- length(claData)
        cx <- c(1:xlength)

        CL <- mean(claData) + cl * sd(claData)

        if(type == "RUNC") {
            RUNC_CL <<- CL
            RUNC_claData <<- claData
            if(!is.null(xindex)){
                cx <- xindex
            }
        }
        if(type == "SDC") {
            SDC_CL <<- CL
            SDC_claData <<- claData
        }
        if(type == "XBARC") {
            XBARC_CL <<- CL
            XBARC_claData <<- claData
        }
        if(type == "RC") {
            RC_CL <<- CL
            RC_claData <<- claData
        }
        if(type == "MRC") {
            MRC_CL <<- CL
            MRC_claData <<- claData
        }
        ucl <- rep(CL[7], times=xlength)
        lcl <- rep(CL[1], times=xlength)
        centerx <- rep(CL[4], times=xlength)
        sigm_m1 <- rep(CL[3], times=xlength)
        sigm_m2 <- rep(CL[2], times=xlength)
        sigm_p1 <- rep(CL[5], times=xlength)
        sigm_p2 <- rep(CL[6], times=xlength)

        dc <- data.frame(x=cx,y=claData, cx=centerx, ucl=ucl, lcl=lcl, sigm_m2=sigm_m2, sigm_m1=sigm_m1, sigm_p1=sigm_p1, sigm_p2=sigm_p2)
        xmean <- mean(range(dc$x))

        p <- ggplot(dc)
        p <- p + geom_line(aes(x=x,y=y), colour="red")
        p <- p + geom_line(aes(x=x,y=centerx), colour="black", linetype="dashed") + annotate("text",x=xmean,y=CL[4],label=paste("U=", sprintf("%.6f", CL[4])),size=3.5,hjust=.5,vjust=-.4, colour="black", alpha=1)
        p <- p + geom_line(aes(x=x,y=sigm_m2), colour="#568A89", linetype="dashed")+ annotate("text",x=xmean,y=CL[2],label=paste("-2s=", sprintf("%.6f", CL[2])),size=3.5,hjust=.5,vjust=-.4, colour="#568A89", alpha=1)
        p <- p + geom_line(aes(x=x,y=sigm_m1), colour="#71843F", linetype="dashed")+ annotate("text",x=xmean,y=CL[3],label=paste("-s=", sprintf("%.6f", CL[3])),size=3.5,hjust=.5,vjust=-.4, colour="#71843F", alpha=1)
        p <- p + geom_line(aes(x=x,y=sigm_p1), colour="#71843F", linetype="dashed")+ annotate("text",x=xmean,y=CL[5],label=paste("s=", sprintf("%.6f", CL[5])),size=3.5,hjust=.5,vjust=-.4, colour="#71843F", alpha=1)
        p <- p + geom_line(aes(x=x,y=sigm_p2), colour="#568A89", linetype="dashed")+ annotate("text",x=xmean,y=CL[6],label=paste("2s=", sprintf("%.6f", CL[6])),size=3.5,hjust=.5,vjust=-.4, colour="#568A89", alpha=1)
        p <- p + geom_line(aes(x=x,y=ucl), colour="brown", linetype="dashed")+ annotate("text",x=xmean,y=CL[7],label=paste("UCL=", sprintf("%.6f", CL[7])),size=3.5,hjust=.5,vjust=-.4, colour="brown", alpha=1)
        p <- p + geom_line(aes(x=x,y=lcl), colour="brown", linetype="dashed")+ annotate("text",x=xmean,y=CL[1],label=paste("LCL=", sprintf("%.6f", CL[1])),size=3.5,hjust=.5,vjust=-.4, colour="brown", alpha=1)
        if (type == "RUNC"){
            if (rLine1Value != "") {
                rLine1Value<-as.double(rLine1Value)
                rLine1Name <- paste(rLine1Name, "=")
                p <- p + geom_line(aes(x=x,y=rLine1Value), colour="blue", linetype="dashed")+ annotate("text",x=xmean,y=rLine1Value,label=paste(rLine1Name, sprintf("%.6f", rLine1Value)),size=3.5,hjust=.5,vjust=-.4, colour="blue", alpha=1)
            }
            if (rLine2Value != "") {
                rLine2Value<-as.double(rLine2Value)
                rLine2Name <- paste(rLine2Name, "=")
                p <- p + geom_line(aes(x=x,y=rLine2Value), colour="blue", linetype="dashed")+ annotate("text",x=xmean,y=rLine2Value,label=paste(rLine2Name, sprintf("%.6f", rLine2Value)),size=3.5,hjust=.5,vjust=-.4, colour="blue", alpha=1)
            }
        }
        if (type == "MRC"){
            if (mrLine1Value != "") {
                mrLine1Name <- paste(mrLine1Name, "=")
                p <- p + geom_line(aes(x=x,y=as.double(mrLine1Value)), colour="blue", linetype="dashed")+ annotate("text",x=xmean,y=as.double(mrLine1Value),label=paste(mrLine1Name, sprintf("%.6f", as.double(mrLine1Value))),size=3.5,hjust=.5,vjust=-.4, colour="blue", alpha=1)
            }
            if (mrLine2Value != "") {
                mrLine2Name <- paste(mrLine2Name, "=")
                p <- p + geom_line(aes(x=x,y=as.double(mrLine2Value)), colour="blue", linetype="dashed")+ annotate("text",x=xmean,y=as.double(mrLine2Value),label=paste(mrLine2Name, sprintf("%.6f", as.double(mrLine2Value))),size=3.5,hjust=.5,vjust=-.4, colour="blue", alpha=1)
            }
        }
        p <- p + xlab("")
        p <- p + ylab("")
        p <- p + ggtitle(t)
    }, error = function(e) {
        dc <- data.frame(x=c(1:10))
        p3 <- ggplot(dc)+ geom_line(aes(x=0,y=0), colour="red") + ggtitle(t)
        p3 <- p3 +annotate("text",x=0,y=0,label="This item can not be build to a chart.",size=4.5,hjust=.5,vjust=-.2)
        return(p3)
    })
    return (p)
}

# save the all plots to disk with the path supported
#chartType <- c("NDC","NO","NO","SDC","NO","NO")
#filePath <- c("/home/ndc.png","NO","NO","/home/stdc.png","NO","NO")
fun.plot2Img <- function(chartType=NULL, filePath=NULL, fileType=NULL) {
    if(is.null(chartType) || is.null(filePath)) {
        print("Invalidate parameters for building image.")
        return (NULL)
    }

    for (i in 1 : length(chartType)) {
        if(chartType[i] == "NDC") {
            png(filePath[i], width=800, height=500)
            print(fun.buildBar(x))
            dev.off()
        } else if(chartType[i] == "NO") {

        } else {
            png(filePath[i], width=800, height=500)
            print(fun.buildRun(x, chartType[i]))
            dev.off()
        }
    }
}


NDC_CL <- NA
NDC_maxValue <- NA
NDC_minValue <- NA

RUNC_CL <- NA
RUNC_claData <- NA
XBARC_CL <- NA
XBARC_claData <- NA
SDC_CL <- NA
SDC_claData <- NA
RC_CL <- NA
RC_claData <- NA
MRC_CL <- NA
MRC_claData <- NA

eval(parse(text=code))
